Tento návod je určen pro úpravu JSON šablon tabulkových sestav (přehledy dokladů, účetní výpisy, ceníky apod.) ve VS Code s live preview.
Obsah:
┌───────────────────────────────────────────────────────────┐
│ XML data + JSON šablona → HTML / PDF │
│ (z aplikace) (vaše úpravy) (výstup) │
└───────────────────────────────────────────────────────────┘
XML data — připraví aplikace (FoxPro). Obsahují reálná data: čísla dokladů, názvy, ceny, datumy.
JSON šablona — tu upravujete vy. Říká rendereru, jak data zobrazit: které sloupce, jaké formáty, skupiny, součty.
Výstup — HTML (náhled v prohlížeči), PDF (tisk), XLSX (Excel).
Editaci spustíte z aplikace. Otevře se VS Code s JSON souborem a v prohlížeči se zobrazí HTML náhled.
Pozor: JSON soubor musí být validní JSON. Nejčastější chyby:
- Čárka za poslední položkou v
{}nebo[]— to v JSON nelze- Chybějící uvozovky:
label: Název→ správně"label": "Název"- Chybějící čárka mezi položkami
Tip: VS Code červeně podtrhne chybu. Ctrl+Z vrátí zpět poslední změnu.
Šablona má tyto hlavní části:
{
"renderer": "table", ← typ šablony (volitelné, pro jednoznačnou identifikaci)
"aliases": { ... }, ← zkratky pro dlouhé XML cesty (volitelné)
"report": { ... }, ← nastavení celé sestavy
"header": { ... }, ← záhlaví (firma, filtr, logo)
"footer": { ... }, ← zápatí
"pageHeader": { ... }, ← záhlaví stránky (opakuje se)
"pageFooter": { ... }, ← zápatí stránky (opakuje se)
"i18n": { ... }, ← překlady textů
"sections": [ ... ] ← sekce s daty (tabulky)
}
report){
"report": {
"title": "Přehled dokladů",
"culture": "cs-CZ",
"orientation": "landscape",
"pageSize": "A4"
}
}
| Vlastnost | Co dělá | Příklad |
|---|---|---|
renderer |
Typ šablony (volitelné — bez něj se typ pozná z obsahu JSON) | "table" |
title |
Název sestavy (zobrazí se v záhlaví) | "Přehled dokladů" |
culture |
Formát čísel a datumů | "cs-CZ" (čárka), "en-US" (tečka) |
orientation |
Orientace stránky | "portrait" (na výšku), "landscape" (na šířku) |
pageSize |
Velikost papíru | "A4", "A3", "Letter" |
pageBreak |
Nová stránka mezi skupinami při tisku | true / false |
| Vlastnost | Co dělá | Příklad |
|---|---|---|
dataFontPt |
Velikost písma dat (v bodech) | 6 (malé), 8 (normální), 10 (větší) |
xlsxScale |
Zvětšení písma v Excelu | 1.3 (o 30 % větší) |
xlsxFreezeHeader |
Ukotvit záhlaví v Excelu (při scrollování) | true |
detailBorders |
Styl čar mezi řádky | "all", "vertical", "none", "h-dashed" |
filterFontSizePt |
Velikost fontu filtru (v bodech) | 12 (pro podnadpis) |
filterStyle |
Styl filtru | "bold" (tučný), "normal" (normální) |
detailBorders)| Hodnota | Jak vypadá |
|---|---|
"all" |
Všechny čáry (mřížka) — výchozí |
"vertical" |
Jen svislé čáry mezi sloupci |
"horizontal" |
Jen vodorovné čáry mezi řádky |
"none" |
Bez vnitřních čar (vnější rámeček zůstává) |
"inner-none" |
Bez čar (i bez rámečku) |
"h-dashed" |
Vodorovné čárkované + svislé plné |
"h-dashed-only" |
Jen vodorovné čárkované (bez svislých) |
header){
"header": {
"company": "EFES spol. s r.o.\nNeklanova 18\n128 00 Praha 2",
"filter": "Období: leden 2026",
"logoFile": "C:\\data\\logo.jpg"
}
}
| Vlastnost | Co dělá | Poznámka |
|---|---|---|
company |
Název firmy (a adresa) | \n = nový řádek. Ignoruje se, pokud XML obsahuje parametr.adresa1 (viz níže). |
filter |
Popis filtru/období | Zobrazí se pod názvem |
logoFile |
Cesta k logu | Zobrazí se vpravo nahoře |
Logo může být i dynamické: "logoFile": "{header.logoFile}" — cesta se načte z XML dat.
parametr.adresa1 a parametr.adresa2Pokud XML data obsahují element parametr s atributy adresa1 a/nebo adresa2, renderer je automaticky použije pro adresu vlevo nahoře — bez ohledu na header.company v JSON:
adresa1 — první řádek, tučně (HTML: 10 pt, PDF: 9 pt)adresa2 — zbytek adresy, víceřádkový (HTML: 9 pt, PDF: 8 pt), rozdělený po řádcích (\n)loBuilder.Push("parametr")
loBuilder.AddAttribute("adresa1", "EFES spol. s r.o.")
loBuilder.AddAttribute("adresa2", "Neklanova 18" + CHR(10) + "128 00 Praha 2")
loBuilder.Pop()
Výsledek v záhlaví (vlevo nahoře):
EFES spol. s r.o. ← tučně
Neklanova 18
128 00 Praha 2
Pokud parametr element v XML chybí nebo nemá atributy adresa1/adresa2, použije se header.company jako dříve.
sections)Sekce jsou nezávislé části sestavy — každá má vlastní sloupce, skupiny a součty.
{
"sections": [
{
"element": "doklady",
"label": "Přehled dokladů",
"columns": { ... },
"groups": [ ... ],
"sumExpressions": [ ... ]
},
{
"element": "rekapitulace",
"label": "Rekapitulace DPH",
"columns": { ... }
}
]
}
| Vlastnost | Co dělá | Příklad |
|---|---|---|
element |
Název XML elementu s daty (povinný). Tečková notace pro vnořené elementy: "objednavka.polozky" |
"doklady" |
label |
Nadpis sekce | "Přehled dokladů" |
rowNumbers |
Číslování řádků | "global" (průběžné), "group" (v rámci skupiny), false (žádné) |
hideZero |
Skrýt nulové hodnoty | true / false |
visibleWhen |
Zobrazit sekci jen když... | "parametry.je_platce_dph" |
where |
Filtr řádků — zobrazí jen řádky splňující podmínku. Umožňuje více sekcí se stejným element ale různými filtry (rozvaha, výkaz zisku a ztráty…) |
"lk1=A", "castka>0" |
Typický případ: XML obsahuje jednu plochou tabulku s aktivy i pasivy rozlišenými atributem lk1. Pomocí "where" vytvoříte dvě sekce ze stejných dat:
{
"sections": [
{
"element": "data",
"label": "AKTIVA",
"where": "lk1=A",
"columns": {
"text": { "label": "Položka" },
"castka": { "label": "Částka", "align": "right", "format": "N2" }
},
"sumExpressions": [{ "field": "castka", "expr": "SUM(castka)", "format": "N2" }],
"sumLabel": "Aktiva celkem"
},
{
"element": "data",
"label": "PASIVA",
"where": "lk1=P",
"columns": {
"text": { "label": "Položka" },
"castka": { "label": "Částka", "align": "right", "format": "N2" }
},
"sumExpressions": [{ "field": "castka", "expr": "SUM(castka)", "format": "N2" }],
"sumLabel": "Pasiva celkem"
}
]
}
Syntaxe where (stejná jako u sumRows):
| Vzor | Příklad | Popis |
|---|---|---|
"pole=hodnota" |
"lk1=A" |
Rovnost (case-insensitive) |
"pole!=hodnota" |
"stav!=Z" |
Nerovnost |
"pole" |
"aktivni" |
Neprázdné, nenulové |
"!pole" |
"!zruseno" |
Prázdné nebo nulové |
"pole>hodnota" |
"castka>0" |
Numerické porovnání |
"pole>=hodnota" |
"castka>=0" |
Numerické porovnání |
Pořadí sekcí se stejným
element: Výstup následuje pořadí JSON (ne pořadí v XML). SekceAKTIVAbude tedy vždy předPASIVAbez ohledu na pořadí řádků v XML.
columns)Sloupce se definují jako objekt — klíč je název XML atributu, hodnota je nastavení:
{
"columns": {
"cislo": { "label": "Číslo", "align": "center", "width": "60px" },
"nazev": { "label": "Název", "align": "left" },
"datum": { "label": "Datum", "align": "center", "format": "dd.MM.yyyy" },
"cena": { "label": "Částka", "align": "right", "format": "N2" },
"pozn": { "hide": true }
}
}
| Vlastnost | Co dělá | Příklad |
|---|---|---|
label |
Text v záhlaví | "Číslo dokladu" |
align |
Zarovnání | "left", "center", "right" |
width |
Šířka | "12c", "15n2", "d", "t", "16.1mm", "80px", "15%" |
format |
Formát čísla/data | viz tabulka níže |
hide |
Skrýt sloupec | true |
hideZero |
Skrýt nulové hodnoty | true |
negativeRed |
Záporná čísla červeně | true |
format)| Formát | Výstup (cs-CZ) | Popis |
|---|---|---|
"N0" |
1 234 |
Celé číslo s oddělovačem tisíců |
"N2" |
1 234,56 |
2 desetinná místa |
"N4" |
1 234,5678 |
4 desetinná místa |
"P" / "P2" |
12,34 % |
Procenta |
"dd.MM.yyyy" |
15.01.2026 |
Datum |
"dd.MM.yyyy HH:mm" |
15.01.2026 14:30 |
Datum a čas |
"50" |
(max 50 znaků) | Tvrdé oříznutí textu |
"50." |
(max 50 znaků + …) | Tvrdé oříznutí + trojtečka (celkem ≤ 50) |
"50w" |
(max 50 znaků) | Oříznutí na poslední celé slovo |
"50w." |
(max 50 znaků + …) | Celé slovo + trojtečka |
"###.###" |
381.002 |
Textová maska |
"Ano;Ne" |
Ano / Ne |
Boolean — truthy→první, falsy→druhá část |
Zkrácení textu — . na konci přidá trojtečku (…), w ořízne na celé slovo.
Číslo s 2 desetinnými místy:
| XML atribut | JSON definice | Výstup (cs-CZ) |
|---|---|---|
cena="1234.5" |
"format": "N2" |
1 234,50 |
Datum:
| XML atribut | JSON definice | Výstup |
|---|---|---|
datum="2026-01-15" |
"format": "dd.MM.yyyy" |
15.01.2026 |
Záporná čísla červeně:
| XML atribut | JSON definice | Výstup |
|---|---|---|
zustatek="-500" |
"format": "N2", "negativeRed": true |
-500,00 |
| Vlastnost | Co dělá | Příklad |
|---|---|---|
expr |
Výpočet z jiných sloupců | "cena * pocet" |
round |
Zaokrouhlení výsledku | 2 (na 2 des. místa) |
running |
Průběžný součet | true |
resetAt |
Reset součtu při změně skupiny | "ucet" |
template |
Šablona textu | "{cena:N2} {mena}" |
suppressRepeat |
Nezobrazit opakovanou hodnotu | true |
noWrap |
Nezalamovat text (PDF: ořízne, XLSX: bez wrap) | true |
maxWidth |
Max. šířka s automatickým zalamováním (HTML: CSS max-width, XLSX: wrap) | "60mm" |
visibleWhen |
Zobrazit sloupec jen když... | "header.je_cizi_mena" |
expr)Sloupec může místo XML hodnoty zobrazit výsledek výpočtu:
{
"celkem": {
"label": "Celkem",
"expr": "cena * pocet",
"format": "N2",
"round": 2,
"align": "right"
},
"s_dph": {
"label": "S DPH",
"expr": "cena * pocet * 1.21",
"format": "N2",
"round": 2,
"align": "right"
}
}
Ve výrazech můžete použít:
cena, pocet, sleva1.21, 100+, -, *, /(cena - sleva) * pocethlavicky.kurz (hodnota z jiného XML elementu)running)Sloupec s running: true zobrazuje narůstající součet:
{
"zustatek": {
"label": "Zůstatek",
"expr": "prijem - vydaj",
"running": true,
"resetAt": "ucet",
"format": "N2",
"align": "right"
}
}
| Řádek | Příjem | Výdaj | Zůstatek |
|---|---|---|---|
| 1 | 1 000 | 0 | 1 000 |
| 2 | 0 | 300 | 700 |
| 3 | 500 | 0 | 1 200 |
resetAt = název skupiny, při jejíž změně se zůstatek vynuluje.
Sloučí hodnoty z více polí do jednoho sloupce:
{
"adresa": {
"label": "Adresa",
"template": "{ulice}, {psc} {mesto}"
},
"cena_mena": {
"label": "Cena",
"template": "{cena:N2} {parametry.mena}"
}
}
V šabloně:
{pole} — vloží hodnotu pole{pole:N2} — formátovaná hodnota (2 des. místa){pole:50} — zkrácení na 50 znaků (tvrdé oříznutí){pole:50.} — oříznutí + trojtečka … (celkem ≤ 50 znaků){pole:50w} — oříznutí na poslední celé slovo ≤ 50 znaků{pole:50w.} — celé slovo + trojtečka{element.pole} — hodnota z jiného XML elementu (tečková notace)\n v template)Znak \n v šabloně vytvoří víceřádkovou buňku:
{
"adresa": {
"label": "Adresa",
"template": "{ulice}\n{psc} {mesto}"
}
}
Výsledek:
┌──────────────────┐
│ Hlavní 15 │
│ 110 00 Praha │
└──────────────────┘
\n se převede na <br>\n jako zalomení řádkuvisibleWhen)Sloupec nebo celá sekce se zobrazí jen pokud je podmínka splněna:
{
"cena_eur": {
"label": "Cena EUR",
"format": "N2",
"visibleWhen": "header.je_cizi_mena"
},
"kurz": {
"label": "Kurz",
"format": "N3",
"visibleWhen": "header.kurz>1"
}
}
| Zápis | Význam | Příklad |
|---|---|---|
"pole" |
Pole má hodnotu (neprázdné) | "header.je_cizi_mena" |
"!pole" |
Pole nemá hodnotu (prázdné) | "!header.je_cizi_mena" |
"pole=hodnota" |
Rovnost (bez ohledu na velká/malá) | "header.mena=EUR" |
"pole!=hodnota" |
Nerovnost | "header.mena!=CZK" |
"pole>hodnota" |
Číslo je větší | "header.kurz>1" |
"pole>=hodnota" |
Číslo je větší nebo rovno | "header.kurz>=1" |
"pole<hodnota" |
Číslo je menší | "header.sazba<21" |
"pole<=hodnota" |
Číslo je menší nebo rovno | "header.sazba<=15" |
"0", "0,00", "0.00">, >=, <, <=) porovnávají jako desetinná čísla"header.kurz>1", "objednavka.hlavicka.mena=EUR"Funguje na:
visibleWhen na sloupcivisibleWhen na sekcisuppressRepeat){
"faktura": {
"label": "Faktura",
"suppressRepeat": true
}
}
| Faktura | Datum | Částka |
|---|---|---|
| FV001 | 15.01. | 1 000 |
| 16.01. | 500 | |
| 17.01. | 200 | |
| FV002 | 18.01. | 3 000 |
Hodnota "FV001" se zobrazí jen jednou. Při změně skupiny se tracker resetuje.
Poznámka: V XLSX výstupu se
suppressRepeatautomaticky ignoruje — Excel uživatel potřebuje kompletní hodnoty pro filtrování, řazení a vzorce.
printColumns)V columns definujete všechny dostupné sloupce. Property printColumns na sekci pak za běhu vybere, které z nich se vytisknou a v jakém pořadí.
{
"sections": [{
"element": "doklady",
"printColumns": "rada,doklad,castka,text",
"columns": {
"rada": { "label": "Řada" },
"doklad": { "label": "Doklad" },
"ucet_md": { "label": "MD" },
"ucet_d": { "label": "D" },
"castka": { "label": "Částka", "format": "N2" },
"text": { "label": "Text" },
"organizace": { "label": "Organizace" }
}
}]
}
→ Vytisknou se jen 4 sloupce: rada, doklad, castka, text.
Dynamický výběr z XML: Pomocí {element.field} se seznam sloupců načte z XML dat:
"printColumns": "{parametry.sloupce}"
Ve FoxPro nastavíte:
loBuilder.AddElement("parametry")
loBuilder.AddAttribute("sloupce", "rada,doklad,castka,text")
loBuilder.Pop()
Uživatel si za běhu volí sloupce, výběr se předá přes XML. Prázdný printColumns nebo prázdné XML pole = tisknou se všechny sloupce.
groups)Skupiny seskupí řádky a zobrazí mezisoučty. Dva režimy:
Data jsou plochá (všechny řádky na jedné úrovni), renderer seskupí podle hodnot atributů:
{
"groups": [
{
"groupExpression": "rada",
"label": "Řada {rada}",
"headerMode": "external",
"tableBreak": true,
"sumExpressions": [
{ "field": "cena", "expr": "SUM(cena)", "format": "N2" }
],
"sumLabel": "Celkem za řadu {rada}"
}
]
}
Pozor: Data musí být setříděná podle skupinových polí! Renderer neřadí data sám — pouze detekuje změny hodnot. V FoxPro zajistěte
ORDER BYv SQL dotazu.
| Vlastnost | Co dělá | Příklad |
|---|---|---|
groupExpression |
Pole pro seskupení | "rada" nebo ["typ", "rada"] |
label |
Nadpis skupiny | "Řada {rada}" — {rada} se nahradí hodnotou |
headerMode |
Styl nadpisu | "external" (nad tabulkou), "inline" (řádek v tabulce) |
tableBreak |
Každá skupina = samostatná tabulka | true / false |
resetRowNumbers |
Číslování od 1 v každé skupině | true |
hideGroupHeader |
Skrýt nadpis skupiny | true (data se stále seskupují) |
hideGroupFooterIfSingle |
Skrýt součet u skupiny s 1 řádkem | true |
forceNewPage |
Začít skupinu na nové stránce | true (jen paged režim) |
reprintHeader |
Znovutisk záhlaví (firma, nadpis, logo) | true — každá skupina = nová sestava |
detailBorders |
Čáry jen pro tuto skupinu | "vertical", "none", "h-dashed" atd. |
sumBorder |
Čára nad součtem | "solid", "dashed", "light", "none" |
sumBorders |
Vnitřní okraje v součtových řádcích | "all", "vertical", "horizontal", "none", "inner-none", "h-dashed", "h-dashed-only" |
sumStyle |
Styl součtových řádků | "bold" (výchozí tučný), "light" (normální písmo) |
sumLabelAlign |
Zarovnání popisku součtu | "right" (výchozí), "left" |
headerBackground |
Barva pozadí group header řádku | "#ffffc0" (hex), "LightYellow" (pojmenovaná), "rgb(255,255,192)" (RGB) |
sumBackground |
Barva pozadí sum řádků | "#ccffcc" (hex), "LightGreen" (pojmenovaná), "#ffffff" (bílá) |
headerLabelField |
Sloupec pro label v group header | "text" — přepne na per-column mód |
headerValues |
Další hodnoty v group header | [{ "field": "poznamka", "value": "{ucty.poznamka}" }] |
xlsxSheetName |
Nový XLSX list pro každou skupinu | "Účet {ucet:###.###}" — template pro název listu |
footerRows |
Bloky pod tabulkou za skupinou | Viz 11f. Bloky pod tabulkou |
Vizuální styl součtových řádků:
- Group subtotal (
.rs) — pozadí#f0f0f0, uniformně tenké čáry 1px #ddd- Grand total (
.rt) — pozadí#e8e8e8, uniformně tlusté čáry 2px #999sumBordersna skupině řídí group subtotal,sumBordersna sekci řídí grand total- U grand total:
"none"a"inner-none"jsou ekvivalentní (rámec zůstává vždy)- U group subtotal:
"inner-none"odstraní i rámec (zcela neviditelné)
{
"groups": [
{
"groupExpression": ["typ", "rada"],
"label": "{typ} — řada {rada}",
"headerMode": "external",
"tableBreak": true,
"sumExpressions": [
{ "field": "cena", "expr": "SUM(cena)", "format": "N2" }
]
},
{
"groupExpression": "sdoklad",
"label": "Doklad {sdoklad}",
"headerMode": "inline",
"tableBreak": false,
"sumExpressions": [
{ "field": "cena", "expr": "SUM(cena)", "format": "N2" }
]
}
]
}
Pořadí v poli = od vnější skupiny (mění se méně často) po vnitřní (mění se častěji).
V placeholderech {field} v label a sumLabel jsou dostupná všechna pole z datového řádku — nejen skupinové pole z groupExpression:
{
"groupExpression": "stredisko",
"label": "Středisko {stredisko} — {stredisko_nazev}",
"sumLabel": "Celkem za {stredisko} — {stredisko_nazev}"
}
label (záhlaví skupiny) — hodnoty z první věty skupiny. Libovolné pole z <row> elementu.sumLabel (patička skupiny) — hodnoty z poslední věty skupiny. Toto odpovídá chování FoxPro (group footer vidí poslední záznam skupiny).sumExpressions)Definují se na skupině (mezisoučty) nebo na sekci (celkový součet):
{
"sumExpressions": [
{ "field": "cena", "expr": "SUM(cena)", "format": "N2" },
{ "field": "pocet", "expr": "COUNT()", "format": "N0" },
{ "field": "prumer", "expr": "AVG(cena)", "format": "N2" },
{ "field": "marze", "expr": "SUM(prodej) - SUM(nakup)","format": "N2" },
{ "field": "jc", "expr": "SUM(cena) / SUM(pocet)", "format": "N2", "round": 2 }
],
"sumLabel": "Celkem"
}
| Výraz | Co počítá |
|---|---|
SUM(pole) |
Součet |
COUNT() |
Počet řádků |
COUNT(pole) |
Počet řádků kde pole má hodnotu |
AVG(pole) |
Průměr |
MIN(pole) |
Minimum |
MAX(pole) |
Maximum |
SUM(a * b) |
Součet součinů |
SUM(a) / SUM(b) |
Podíl součtů |
V sumLabel fungují placeholdery: "Celkem za řadu {rada}".
Součtový řádek může místo prosté formátované hodnoty zobrazit šablonu s textem:
{
"sumExpressions": [
{
"field": "cena",
"expr": "SUM(cena)",
"template": "{value:N2} {parametry.mena}"
}
]
}
Výsledek: "75 020,00 EUR" místo prostého "75 020,00". Placeholdery v template:
{value:N2} — vypočtená hodnota tohoto expr (nejjednodušší){SUM(cena):N2} — agregátní výraz (lze i jiný než v expr){parametry.mena} — hodnota z jiného XML elementusumRows)Pokud potřebujete pod skupinou nebo sekcí více součtových řádků (např. celkem + splatné + po splatnosti), použijte sumRows místo sumExpressions + sumLabel:
{
"sumRows": [
{
"sumLabel": "Celkem",
"labelField": "text",
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)", "format": "N2" },
{ "field": "d", "expr": "SUM(d)", "format": "N2" }
]
},
{
"sumLabel": "Splatné",
"labelField": "text",
"where": "stav=S",
"sumBorder": "none"
},
{
"sumLabel": "Po splatnosti",
"labelField": "text",
"where": "stav=P",
"sumBorder": "none",
"style": "bold",
"hideIfZero": true
}
]
}
| Vlastnost | Typ | Popis |
|---|---|---|
sumLabel |
string | Popisek řádku ({field} placeholdery fungují) |
labelField |
string | Název sloupce pro label. Bez toho se label rozprostře přes textové sloupce |
where |
string | Filtr: "stav=S" (rovnost), "stav!=P" (nerovnost), "castka>1000" / ">=500" / "<100" / "<=50" (numerické), "stav" (neprázdné), "!stav" (prázdné) |
sumExpressions |
array | Vlastní výrazy. Pokud chybí, dědí z prvního řádku který je má |
sumBorder |
string | Čára nad řádkem: "solid" (auto pro 1.), "none" (auto pro 2.+), "dashed", "light" |
hideIfZero |
bool | Přeskočit řádek pokud všechny výsledky jsou nulové |
style |
string | "bold" (výchozí) nebo "light" (normální váha písma, stejná velikost jako detail) |
labelAlign |
string | "right" (výchozí) nebo "left" — zarovnání popisku |
Dědění výrazů: Druhý a třetí řádek nemá sumExpressions — automaticky použije výrazy z prvního řádku, jen je vyhodnotí jen pro řádky vyhovující podmínce where.
Pozor:
sumRowsasumExpressions+sumLabelse navzájem vylučují. Pokud na skupině/sekci mátesumRows, nepoužívejte současněsumExpressions+sumLabel. Starý formát bezsumRowsfunguje beze změn.
Na skupině můžete nastavit barvy pozadí záhlaví a patičky:
{
"groupExpression": "ucet",
"headerBackground": "#ffffc0",
"sumBackground": "#ffffff"
}
| Vlastnost | Co dělá | Výchozí |
|---|---|---|
headerBackground |
Barva pozadí group header řádku | #e8f4fc (světle modrá) |
sumBackground |
Barva pozadí sum (patičkových) řádků | #f0f0f0 (subtotal), #e8e8e8 (grand total) |
Podporované formáty barev — headerBackground, sumBackground a background na sumExpression:
"LightYellow", "red", "darkgreen", "lightblue" atd. (case-insensitive)"#ffffc0", "#F00" (6-znakový nebo 3-znakový formát)"rgb(255, 255, 192)" s hodnotami 0–255"rgba(255, 255, 192, 0.8)" — alfa kanál se používá jen v HTMLPříklady: "LightYellow", "#ffffc0", "rgb(255, 255, 192)" — všechny jsou ekvivalentní a produkují stejnou žlutou barvu.
Standardně se label skupiny zobrazí jako colspan přes celou šířku. S headerLabelField se label umístí do konkrétního sloupce, headerValues přidají další hodnoty do jiných sloupců:
{
"groupExpression": "ucet",
"label": "{ucet:###.###} {ucty.nazev}",
"headerLabelField": "text",
"headerBackground": "#ffffc0",
"headerValues": [
{ "field": "poznamka", "value": "{ucty.poznamka}", "style": "bold" }
]
}
Výsledek: label "067.200 Půjčka Greens Apple" se zobrazí ve sloupci text, hodnota "{ucty.poznamka}" ve sloupci poznamka. Buňky s obsahem automaticky zabírají sousední prázdné sloupce (auto-colspan).
Na sumExpression lze přidat per-cell overrides (align, background, style), nebo zobrazit neagregátní hodnotu z lookup kontextu (value místo expr):
{
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)", "format": "N2" },
{ "field": "dal", "expr": "SUM(dal)", "format": "N2" },
{ "field": "poznamka", "value": "{ucty.poznamka}", "align": "right", "background": "#c0e0ff", "style": "bold" }
]
}
Třetí výraz neagreguje — value zobrazí textovou hodnotu z lookup kontextu s modrým pozadím, tučným písmem a pravým zarovnáním.
headerRows)Property headerRows umožňuje vytvořit záhlaví ve více řádcích — typicky pro seskupení sloupců:
{
"sections": [{
"element": "data",
"headerRows": [
[
{ "text": "Identifikace", "colspan": 2, "align": "center" },
{ "text": "Hodnoty", "colspan": 2, "align": "center", "background": "#e0f0ff" }
],
[
{ "text": "Kategorie" },
{ "text": "Název" },
{ "text": "Ks", "align": "right" },
{ "text": "Celkem", "align": "right" }
]
],
"columns": {
"kategorie": { "label": "Kategorie" },
"nazev": { "label": "Název" },
"ks": { "label": "Ks", "align": "right", "format": "N0" },
"celkem": { "label": "Celkem", "align": "right", "format": "N0" }
}
}]
}
Výsledek: první řádek záhlaví zobrazí skupinové nadpisy ("Identifikace" přes 2 sloupce, "Hodnoty" přes 2 sloupce), druhý řádek zobrazí názvy jednotlivých sloupců.
Vlastnosti buňky záhlaví:
| Vlastnost | Popis |
|---|---|
text |
Text buňky |
colspan |
Počet sloupců které buňka zabere (výchozí 1) |
rowspan |
Počet řádků které buňka zabere (výchozí 1) |
align |
"left", "center", "right" — null = zarovnání ze sloupce |
style |
"bold" (výchozí) nebo "normal" |
background |
CSS barva pozadí buňky (#rrggbb) |
Pokud
headerRowschybí, použijí selabelzecolumnsjako jednořádkové záhlaví (zpětná kompatibilita).
subFields)Pod každým datovým řádkem se mohou zobrazit doplňkové údaje — EAN, šarže, poznámka apod.:
{
"sections": [{
"element": "polozky",
"columns": {
"nazev": { "label": "Název" },
"cena": { "label": "Cena", "format": "N2" }
},
"subFields": [
{ "field": "ean", "label": "EAN" },
{ "field": "sarze", "label": "Šarže", "format": "dd.MM.yyyy" },
{ "field": "poznamka" }
]
}]
}
Výstup: pod datovým řádkem se zobrazí např. EAN: 8594001234567 · Šarže: 15.01.2026 · Poznámka textu.
| Vlastnost | Co dělá | Příklad |
|---|---|---|
field |
Název XML atributu | "ean" |
label |
Popisek před hodnotou | "EAN" (zobrazí EAN: hodnota) |
format |
Formát hodnoty | "dd.MM.yyyy", "N2" |
visibleWhen |
Podmíněná viditelnost | "stav" / "!stav" |
Auto-hiding: Pokud jsou všechna subFields pro daný řádek prázdná, podřádek se přeskočí.
sumSpacerMm)Vlastnost sumSpacerMm na sekci vloží prázdný řádek o zadané výšce před grand total:
{
"sections": [{
"element": "data",
"sumSpacerMm": 3,
"sumExpressions": [
{ "field": "cena", "expr": "SUM(cena)", "format": "N2" }
],
"sumLabel": "Celkem"
}]
}
Výchozí hodnota je 0 (žádná mezera). Vizuálně oddělí poslední datový řádek od součtu.
Hodnoty začínající znakem ^ se renderují jako Markdown. Bez prefixu = prostý text (beze změny).
pozn="^**důležité**" → tučný text v buňce^, renderuje se jako Markdownsarze="^==exp 01/2026==" → zvýrazněný text| Zápis | Výsledek |
|---|---|
**tučný** |
tučný |
*kurzíva* |
kurzíva |
==zvýrazněný== |
zvýrazněný text (žlutě) |
- položka |
odrážkový seznam |
[odkaz](url) |
klikatelný odkaz |
Pokud chcete formátovat buňku, která kombinuje více polí, použijte template začínající ^:
{
"nazev_pozn": {
"label": "Název",
"template": "^**{nazev}**\n{poznamka}"
}
}
Výsledek: název tučně, pod ním poznámka normálním písmem — vše v jedné buňce.
Pozor:
- Prefix
^se automaticky odstraní — výstup neobsahuje stříšku- V PDF se Markdown převádí na bold/italic/underline (složitější formátování se redukuje na text)
- V XLSX se Markdown tagy odstraní — zobrazí se prostý text
footerRows)Za součtovými řádky skupiny (nebo za grand totalem sekce) lze přidat bloky — popisky, hodnoty, podmíněné texty, podpisy. Typické pro inventarizační výkazy, protokoly, rekapitulace.
| Typ | Co dělá |
|---|---|
spacer |
Prázdné místo (výška v mm) |
label-value |
Popisek + hodnota (např. „Účetní stav: 71 127,33 Kč") |
text |
Volný text (podmíněný nebo statický) |
signature |
Dva podpisy vedle sebe |
{
"groups": [{
"groupExpression": "ucet",
"label": "Účet {ucet:###.###}",
"sumExpressions": [{ "field": "castka", "expr": "SUM(castka)", "format": "N2" }],
"footerRows": [
{ "type": "spacer", "heightMm": 3 },
{ "type": "label-value", "label": "Účetní stav:", "template": "{ucetni_stav:N2} Kč",
"labelField": "text", "valueField": "md", "style": "bold", "fontSizePt": 10 },
{ "type": "label-value", "label": "Zjištěný stav:", "template": "{zjisteny_stav:N2} Kč",
"labelField": "text", "valueField": "md", "fontSizePt": 10 },
{ "type": "label-value", "label": "Rozdíl:", "template": "{rozdil:N2} Kč",
"labelField": "text", "valueField": "md", "style": "bold", "fontSizePt": 10 },
{ "type": "text", "text": "Inventarizační komise navrhuje odpis rozdílu.",
"visibleWhen": "rozdil" },
{ "type": "signature", "signatureLeft": "Předseda komise",
"signatureRight": "Člen komise" }
]
}]
}
| Vlastnost | Co dělá | Příklad |
|---|---|---|
type |
Typ bloku | "spacer", "label-value", "text", "signature" |
label |
Popisek (label-value) | "Účetní stav:" |
template |
Šablona hodnoty s placeholdery | "{castka:N2} Kč" |
value |
Přímá šablona hodnoty | "{ucetni_stav:N2}" |
field + format |
Pole z XML + formát | "castka" + "N2" |
text |
Text pro typ "text" | "Inventarizační komise navrhuje..." |
style |
Styl písma | "bold", "normal", "title" |
fontSizePt |
Velikost fontu | 10, 12 |
visibleWhen |
Podmíněná viditelnost | "rozdil", "!rozdil", "SUM(rozdil)", "!SUM(rozdil)" |
labelField |
Zarovnání labelu na sloupec | "text" (dle sloupce v tabulce) |
valueField |
Zarovnání hodnoty na sloupec | "md" (dle sloupce v tabulce) |
signatureLeft |
Levý podpis | "Předseda komise" |
signatureRight |
Pravý podpis | "Člen komise" |
heightMm |
Výška spaceru v mm | 3, 5 |
Renderer hledá hodnotu v tomto pořadí:
template — šablona s placeholdery: "{castka:N2} {mena}"value — přímá šablona: "{ucetni_stav:N2}"field + format — prosté pole s formátemFooter rows se zobrazují mimo tabulku, ale mohou být vizuálně zarovnány ke sloupcům tabulky:
labelField + valueField — label pod sloupcem labelField, value pod sloupcem valueFieldlabelField — label pod sloupcem, value hned za nímfooterRows na skupině — zobrazí se po uzavření každé skupiny (za součtovými řádky)footerRows na sekci (top-level) — zobrazí se po grand total{
"sections": [{
"element": "data",
"groups": [{ "groupExpression": "ucet", "footerRows": [...] }],
"footerRows": [
{ "type": "text", "text": "Celkový přehled za {header.obdobi}", "style": "title" }
]
}]
}
visibleWhen a template/value ve footerRows podporují agregátní výrazy: SUM(), AVG(), MIN(), MAX(), COUNT().
{
"footerRows": [
{ "type": "label-value", "label": "Rozdíl:", "template": "{SUM(rozdil):N2} Kč", "style": "bold" },
{ "type": "text", "text": "Stav souhlasí.", "visibleWhen": "!SUM(rozdil)" },
{ "type": "text", "text": "Komise navrhuje odpis.", "visibleWhen": "SUM(rozdil)", "style": "bold" }
]
}
"visibleWhen": "SUM(rozdil)" — viditelné pokud součet rozdílů není nulový"visibleWhen": "!SUM(rozdil)" — viditelné pokud součet rozdílů je nulový"template": "{SUM(rozdil):N2}" — zobrazí vypočtený součet s formátemTip: Na skupině se agregáty počítají z řádků dané skupiny. Na sekci se počítají ze všech řádků sekce.
xlsxSheetName)V XLSX výstupu může každá skupina vytvořit nový worksheet:
{
"groupExpression": "ucet",
"xlsxSheetName": "Účet {ucet:###.###}"
}
Název listu se resolvuje z dat skupiny. Neplatné znaky se automaticky odstraní (max 31 znaků). Pouze pro XLSX — HTML a PDF tuto vlastnost ignorují (tam se používá forceNewPage/tableBreak).
Tip: Pokud chcete nový list i bez šablony názvu, použijte
forceNewPage: true— v XLSX se automaticky vytvoří nový list s názvem z group label.
Doplní data z jiné XML tabulky (např. název firmy k číslu organizace):
{
"groupExpression": "organizace",
"label": "{organizace} {adresy.orgnazev:80}",
"lookup": { "element": "adresy" }
}
Renderer dohledá v XML elementu <adresy> řádek se shodnou hodnotou organizace a zpřístupní jeho atributy.
{
"lookup": [
{ "element": "hlavicky_dokladu" },
{ "element": "adresy", "key": "organizace" }
]
}
Krok 1: dohledá hlavičku dokladu. Krok 2: z hlavičky vezme organizace a dohledá adresu.
{firma}, {den:dd.MM.yyyy} — přímo jménem atributu"expr": "cena * hlavicky.kurz" — tečková notace"template": "{cena:N2} {hlavicky.mena}" — tečková notaceLookup nemusí být jen na skupině — lze ho definovat přímo na sekci. Pak se provádí per-row (pro každý řádek zvlášť):
{
"sections": [
{
"element": "polozky",
"lookup": { "element": "sklad", "key": "kod_zbozi" },
"columns": {
"kod_zbozi": { "label": "Kód" },
"sklad.nazev": { "label": "Název zboží" },
"pocet": { "label": "Množství", "format": "N2" }
}
}
]
}
Pro každý řádek v <polozky> se dohledá odpovídající řádek v <sklad> podle kod_zbozi a zpřístupní se jeho atributy přes tečkovou notaci (sklad.nazev).
aliases)Pokud v šabloně opakovaně používáte dlouhé tečkové cesty, můžete si definovat zkratky:
{
"aliases": {
"pol": "objednavka.polozky",
"hlav": "objednavka.hlavicka"
},
"sections": [{
"element": "pol",
"columns": {
"cena": { "label": "Cena {hlav.mena}", "format": "N2" }
}
}]
}
element, visibleWhen, template, label, expr, where a dalších místech{hlav.mena} → {objednavka.hlavicka.mena}Typický případ: Předvaha — tři úrovně účtů (syn1, syn2, syn3), všechny hledají v jednom elementu syn_ucty. Každý alias vytvoří vlastní lookup session (cache se nestírají):
{
"aliases": {
"syn_ucty1": "syn_ucty",
"syn_ucty2": "syn_ucty",
"syn_ucty3": "syn_ucty"
},
"sections": [{
"element": "data",
"groups": [
{
"groupExpression": "syn1",
"label": "{syn1} {syn_ucty1.nazev}",
"lookup": { "element": "syn_ucty1", "key": "syn1", "foreignKey": "syn" },
"sumLabel": "Σ {syn1} {syn_ucty1.nazev}"
},
{
"groupExpression": "syn2",
"label": "{syn2} {syn_ucty2.nazev}",
"lookup": { "element": "syn_ucty2", "key": "syn2", "foreignKey": "syn" }
},
{
"groupExpression": "syn3",
"label": "{syn3} {syn_ucty3.nazev}",
"lookup": { "element": "syn_ucty3", "key": "syn3", "foreignKey": "syn" }
}
]
}]
}
V XML stačí jeden element syn_ucty:
<syn_ucty>
<row syn="0" nazev="Dlouhodobý majetek" />
<row syn="01" nazev="Dlouhodobý nehmotný majetek" />
<row syn="011" nazev="Zřizovací výdaje" />
</syn_ucty>
Při otevření editoru přes OpenReportEditor() se aliasy automaticky přidají do VS Code IntelliSense — nabídnou se jako syn_ucty1, syn_ucty2, syn_ucty3 s poli syn a nazev.
Záhlaví sloupce může obsahovat hodnotu z XML:
{
"cena": {
"label": "Cena {parametry.mena}",
"format": "N2"
}
}
Záhlaví se zobrazí jako: Cena EUR (pokud <parametry mena="EUR" />).
Pro sestavy s mnoha stránkami:
{
"report": {
"pageLayout": "paged",
"orientation": "landscape",
"pageMarginMm": 8
},
"pageHeader": {
"left": "{company}",
"center": "{title}",
"right": "Strana {page} z {pages}"
},
"pageFooter": {
"left": "Vytištěno: {date}",
"right": "{filter}"
}
}
Placeholdery v záhlaví/zápatí stránky:
| Placeholder | Co zobrazí |
|---|---|
{page} |
Číslo stránky |
{pages} |
Celkový počet stránek |
{title} |
Název sestavy |
{company} |
Název firmy |
{date} |
Aktuální datum (dd.MM.yyyy) |
{datetime} |
Aktuální datum a čas (dd.MM.yyyy HH:mm:ss) |
{filter} |
Filtr z header.filter |
Vlastnost fromPage (číslo) na pageHeader/pageFooter umožňuje zobrazit záhlaví/zápatí až od dané stránky (např. "fromPage": 2).
Tip: Přetečení stránky v tisku Pokud sestava v prohlížeči vypadá správně, ale v tisku přeteče na další stránku, je to způsobeno kumulativními odchylkami CSS renderingu (padding, border, line-height). Vlastnost
pageSafetyMarginMm(výchozí5) kompenzuje tyto odchylky. Pokud stále přetéká, zvyšte hodnotu (např."pageSafetyMarginMm": 8). Nastavení0bezpečnostní okraj vypne.
i18n)Překlad textů v sestavě:
{
"i18n": {
"Celkem": "Total",
"Strana": "Page"
}
}
ShowProgress)Při generování velkých sestav (stovky řádků) lze zobrazit dialog s průběhem a tlačítkem Storno:
loBuilder.ShowProgress = .T.
loBuilder.Render("sestava.pdf", "sablona.json") && dialog s průběhem
loBuilder.ShowProgress = .F. && zpět bez dialogu
Dialog zobrazuje:
Řádek 450 / 1 200Render() vrátí .F.Tip: Property
ShowProgresspřežíváReset()iEndBatch(). Stačí nastavit jednou a funguje pro všechna voláníRender().
Existující FoxPro FRX reporty lze automaticky konvertovat na JSON šablony:
*--- Auto-detekce typu (table/document) ---
loBuilder.ConvertFrxToAllFiles("C:\frx\CENIK.xml", "C:\output\")
*--- Pokud auto-detekce špatně klasifikuje typ ---
loBuilder.ConvertFrxToTableReportAllFiles("C:\frx\CENIK.xml", "C:\output\")
loBuilder.ConvertFrxToDocumentAllFiles("C:\frx\INVUCKC.xml", "C:\output\")
Výstup: 3 soubory ve výstupní složce — .json (šablona), _sample.xml (vzorová data), .prg (FoxPro kód).
Varianty jen pro JSON soubor:
loBuilder.ConvertFrxToJsonFile("CENIK.xml", "cenik.json") && auto-detekce
loBuilder.ConvertFrxToTableReportJsonFile("CENIK.xml", "cenik.json") && vynuceně tabulka
loBuilder.ConvertFrxToDocumentJsonFile("INVUCKC.xml", "invuckc.json") && vynuceně dokument
Tip: Auto-detekce typu se řídí výškami bandů a počtem polí. Pokud výsledek nevypadá správně, použijte variantu s vynuceným typem (
TableReportneboDocumentv názvu metody).
{
"report": {
"title": "Ceník",
"culture": "cs-CZ"
},
"header": {
"company": "EFES spol. s r.o."
},
"sections": [
{
"element": "polozky",
"columns": {
"kod": { "label": "Kód", "align": "center", "width": "60px" },
"nazev": { "label": "Název" },
"cena": { "label": "Cena/ks", "align": "right", "format": "N2" },
"mj": { "label": "MJ", "align": "center", "width": "40px" }
}
}
]
}
{
"report": {
"title": "Saldokonto",
"culture": "cs-CZ",
"detailBorders": "vertical",
"xlsxScale": 1.3
},
"sections": [
{
"element": "pohyby",
"hideZero": true,
"columns": {
"faktura": { "label": "Faktura", "suppressRepeat": true },
"den": { "label": "Datum", "format": "dd.MM.yyyy" },
"md": { "label": "Má dáti", "format": "N2", "align": "right", "negativeRed": true },
"d": { "label": "Dal", "format": "N2", "align": "right" },
"zust": { "label": "Zůstatek", "expr": "md - d", "running": true,
"resetAt": "organizace", "format": "N2", "align": "right" }
},
"groups": [
{
"groupExpression": "organizace",
"label": "{organizace} {adresy.orgnazev:80}",
"headerMode": "external",
"tableBreak": true,
"lookup": { "element": "adresy" },
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)", "format": "N2" },
{ "field": "d", "expr": "SUM(d)", "format": "N2" },
{ "field": "zust", "expr": "SUM(md) - SUM(d)", "format": "N2" }
]
}
],
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)", "format": "N2" },
{ "field": "d", "expr": "SUM(d)", "format": "N2" },
{ "field": "zust", "expr": "SUM(md) - SUM(d)", "format": "N2" }
],
"sumLabel": "Celkem"
}
]
}
{
"sections": [
{
"element": "polozky",
"columns": {
"nazev": { "label": "Název" },
"cena": { "label": "Cena Kč", "format": "N2", "align": "right",
"visibleWhen": "!header.je_cizi_mena" },
"cizi": { "label": "Cena {header.mena}", "format": "N2", "align": "right",
"visibleWhen": "header.je_cizi_mena" },
"kurz": { "label": "Kurz", "format": "N3",
"visibleWhen": "header.je_cizi_mena" }
}
}
]
}
Hlavní kniha (účetní sestava) je typický příklad složitého reportu, kde potřebujete:
Sestava má typicky 3 úrovně skupin:
Normálně sumExpressions počítá součty přes řádky aktuální skupiny. Na vnitřní skupině (období) ale často potřebujete KZ (konečný zůstatek), který se počítá přes všechny řádky účtu — tedy přes nadřazenou skupinu.
Property "scope" na sumRow říká: "pro tento součet vezmi řádky z jiné skupiny".
{
"groupExpression": "obdobi",
"sumRows": [
{
"sumLabel": "KZ k m.{obdobi}",
"scope": "ucet",
"where": "obdobi<={obdobi}",
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)-SUM(d)", "format": "N2" }
]
}
]
}
Hodnota "scope" je název groupExpression nadřazené skupiny (zde "ucet"). Renderer vezme všechny řádky dané skupiny účtu a teprve na nich aplikuje where filtr.
Podmínka "where" na sumRow může obsahovat {field} placeholder, který se nahradí hodnotou z aktuální skupiny:
{
"sumLabel": "PZ k m.{obdobi}",
"scope": "ucet",
"where": "obdobi<{obdobi}"
}
Pokud je aktuální období 2, podmínka se resolvuje na "obdobi<2" — výsledek zahrnuje jen řádky období 0 a 1. Díky tomu můžete na vnitřní skupině (období) spočítat kumulativní zůstatek k aktuálnímu měsíci.
Ternární výraz umožňuje podmíněný výpočet v součtovém řádku. Syntaxe: podmínka?výraz_true:výraz_false.
{
"sumExpressions": [
{ "field": "md", "expr": "osnova.ap=A?SUM(md)-SUM(d):0", "format": "N2" },
{ "field": "d", "expr": "osnova.ap=P?SUM(d)-SUM(md):0", "format": "N2" }
]
}
Podmínka osnova.ap=A se vyhodnotí z lookup tabulky (osnova účtů). Pokud je účet aktivní (A), zobrazí se MD-D, jinak se zobrazí 0. Pro pasivní účet (P) naopak D-MD.
Ternární výrazy lze řetězit: a=1?X:a=2?Y:Z — funguje jako if-elseif-else.
Pro syntetiku (vnější skupinu), která obsahuje mix aktivních a pasivních účtů, nestačí prostý ternární výraz — ten se vyhodnotí jen jednou pro celou syntetiku. SUMBY řeší tento problém: rozparticionuje řádky podle zadaného pole a pro každou partici vyhodnotí výraz zvlášť.
{
"sumLabel": "KZ syntetika",
"sumExpressions": [
{ "field": "md", "expr": "SUMBY(ucet, osnova.ap=A?SUM(md)-SUM(d):0)", "format": "N2" },
{ "field": "d", "expr": "SUMBY(ucet, osnova.ap=P?SUM(d)-SUM(md):0)", "format": "N2" }
]
}
SUMBY(ucet, ...) znamená: rozděl řádky syntetiky podle hodnoty ucet, pro každý účet vyhodnoť vnitřní výraz (s jeho lookup kontextem z osnovy) a výsledky sečti.
Property "visibleWhen" na součtovém řádku řídí, zda se řádek zobrazí. Podmínka se vyhodnocuje z aktuálního group elementu:
{
"sumLabel": "Obrat m.{obdobi}",
"visibleWhen": "obdobi>0",
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)", "format": "N2" }
]
}
Řádek "Obrat" se zobrazí jen pro období > 0 (ne pro počáteční zůstatky). Pro období 0 (PZ) se řádek přeskočí.
Property "hideZero": true na jednotlivé sumExpression způsobí, že pokud je výsledek výrazu nula, buňka zůstane prázdná (místo zobrazení "0,00"):
{ "field": "md", "expr": "osnova.ap=A?SUM(md)-SUM(d):0", "format": "N2", "hideZero": true }
Typické použití: v Hlavní knize je KZ na straně MD jen u aktivních účtů, u pasivních je 0 — prázdná buňka je přehlednější než "0,00".
Vlastnosti "forceNewPage" a "tableBreak" mohou být místo true/false zadané jako placeholder, který se resolvuje z XML dat:
{
"groupExpression": "ucet",
"forceNewPage": "{parametr.lstrankovat}",
"tableBreak": "{parametr.lstrankovat}"
}
FoxPro kód nastaví lstrankovat na .t. nebo .f. a renderer automaticky přepne stránkování za běhu. Hodnoty "1", ".t.", "true", "yes" se interpretují jako true, ostatní jako false.
{
"renderer": "table",
"report": {
"title": "Hlavní kniha",
"culture": "cs-CZ",
"pageLayout": "paged",
"dataFontPt": 8
},
"header": { "company": "Firma s.r.o." },
"pageHeader": {
"left": "{company}", "center": "{title}",
"right": "Strana {page} z {pages}", "heightMm": 10, "fromPage": 2
},
"sections": [{
"element": "data",
"columns": {
"den": { "label": "Den", "align": "center", "format": "dd.MM.yyyy", "width": "15.6mm" },
"doklad": { "label": "Doklad", "template": "{rada} {doklad}", "align": "center", "width": "13.2mm" },
"text": { "label": "Text", "width": "44.4mm" },
"md": { "label": "Má dáti","align": "right", "format": "N2", "hideZero": true, "width": "31.5mm" },
"d": { "label": "Dal", "align": "right", "format": "N2", "hideZero": true, "width": "31mm" }
},
"groups": [
{
"groupExpression": "syn",
"label": "{syn} {syn_ucty.nazev}",
"lookup": { "element": "syn_ucty", "key": "syn" },
"tableBreak": true,
"headerMode": "external",
"sumRows": [
{
"sumLabel": "PZ syntetika", "where": "obdobi=0",
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)", "format": "N2" },
{ "field": "d", "expr": "SUM(d)", "format": "N2" }
]
},
{
"sumLabel": "Obraty syntetika", "where": "obdobi>0",
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)", "format": "N2" },
{ "field": "d", "expr": "SUM(d)", "format": "N2" }
]
},
{
"sumLabel": "KZ syntetika",
"sumExpressions": [
{ "field": "md", "expr": "SUMBY(ucet, osnova.ap=A?SUM(md)-SUM(d):0)", "format": "N2", "hideZero": true },
{ "field": "d", "expr": "SUMBY(ucet, osnova.ap=P?SUM(d)-SUM(md):0)", "format": "N2", "hideZero": true }
],
"style": "bold"
}
]
},
{
"groupExpression": "ucet",
"label": "{ucet} {osnova.nazev}",
"lookup": { "element": "osnova", "key": "ucet" },
"forceNewPage": "{parametr.lstrankovat}",
"tableBreak": "{parametr.lstrankovat}",
"headerMode": "inline",
"sumRows": [
{
"sumLabel": "PZ {ucet}", "where": "obdobi=0",
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)", "format": "N2" },
{ "field": "d", "expr": "SUM(d)", "format": "N2" }
]
},
{
"sumLabel": "Obrat {ucet}", "where": "obdobi>0",
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)", "format": "N2" },
{ "field": "d", "expr": "SUM(d)", "format": "N2" }
]
},
{
"sumLabel": "KZ {ucet}",
"sumExpressions": [
{ "field": "md", "expr": "osnova.ap=A?SUM(md)-SUM(d):0", "format": "N2", "hideZero": true },
{ "field": "d", "expr": "osnova.ap=P?SUM(d)-SUM(md):0", "format": "N2", "hideZero": true }
],
"style": "bold"
}
]
},
{
"groupExpression": "obdobi",
"hideGroupHeader": true,
"tableBreak": false,
"headerMode": "inline",
"sumRows": [
{
"sumLabel": "PZ k m.{obdobi}",
"scope": "ucet",
"where": "obdobi<{obdobi}",
"visibleWhen": "obdobi>0",
"sumExpressions": [
{ "field": "md", "expr": "osnova.ap=A?SUM(md)-SUM(d):0", "format": "N2", "hideZero": true },
{ "field": "d", "expr": "osnova.ap=P?SUM(d)-SUM(md):0", "format": "N2", "hideZero": true }
],
"sumBorder": "none"
},
{
"sumLabel": "Obrat m.{obdobi}",
"visibleWhen": "obdobi>0",
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)", "format": "N2" },
{ "field": "d", "expr": "SUM(d)", "format": "N2" }
],
"sumBorder": "dashed"
},
{
"sumLabel": "KZ k m.{obdobi}",
"scope": "ucet",
"where": "obdobi<={obdobi}",
"sumExpressions": [
{ "field": "md", "expr": "osnova.ap=A?SUM(md)-SUM(d):0", "format": "N2", "hideZero": true },
{ "field": "d", "expr": "osnova.ap=P?SUM(d)-SUM(md):0", "format": "N2", "hideZero": true }
],
"style": "bold"
}
]
}
],
"sumRows": [
{
"sumLabel": "PZ Celkem", "where": "obdobi=0",
"sumExpressions": [
{ "field": "md", "expr": "SUM(md)", "format": "N2" },
{ "field": "d", "expr": "SUM(d)", "format": "N2" }
]
},
{
"sumLabel": "KZ celkem",
"sumExpressions": [
{ "field": "md", "expr": "SUMBY(ucet, osnova.ap=A?SUM(md)-SUM(d):0)", "format": "N2", "hideZero": true },
{ "field": "d", "expr": "SUMBY(ucet, osnova.ap=P?SUM(d)-SUM(md):0)", "format": "N2", "hideZero": true }
],
"style": "bold"
}
]
}]
}
Tip: Lookup tabulky
syn_uctyaosnovaobsahují názvy syntetik a účtů. FoxPro je přidá přesAddElementWithXmlContent. Data musí být setříděná podle skupin: nejprve syn, pak ucet, pak obdobi.
Sada drobných vylepšení, která zvyšují přehlednost a použitelnost sestav. Všechna fungují ve všech třech výstupních formátech (HTML, PDF, XLSX), pokud není uvedeno jinak.
Vlastnost "watermark" v sekci report zobrazí velký průhledný text diagonálně přes celou stránku. Podporuje {element.field} placeholdery — pokud se placeholder resolvuje na prázdný řetězec, watermark se nezobrazí.
{
"report": {
"watermark": "{parametr.stav}"
}
}
Pokud XML obsahuje <parametr stav="NÁVRH" />, zobrazí se vodoznak "NÁVRH". Pokud je atribut prázdný nebo element chybí, vodoznak se nezobrazí.
Lze zadat i statický text:
{
"report": {
"watermark": "KONCEPT"
}
}
Modifikátor se přidá za formát (nebo místo formátu) a změní velikost písmen ve výsledné hodnotě:
| Modifikátor | Výsledek | Příklad |
|---|---|---|
:UPPER |
Vše velkými | "produkt alfa" → "PRODUKT ALFA" |
:LOWER |
Vše malými | "PRODUKT" → "produkt" |
:PROPER |
Každé slovo velké | "jan novák" → "Jan Novák" |
Modifikátor funguje na sloupci (format) i v template placeholderech ({pole:PROPER}):
{
"columns": {
"kod": { "label": "Kód", "format": "UPPER" },
"nazev": { "label": "Název", "format": "PROPER" },
"popis": { "label": "Popis", "template": "{prijmeni:UPPER} {jmeno:PROPER}" }
}
}
Modifikátor lze kombinovat s formátem: "format": "N2:UPPER" — nejprve se aplikuje formát, pak modifikátor.
Syntaxe s | (svislítkem) umožňuje zadat řetězec záložních hodnot. Použije se první neprázdná:
{
"columns": {
"kontakt": { "label": "Kontakt", "template": "{email|telefon|'neuvedeno'}" }
}
}
email, zobrazí se email.telefon, zobrazí se telefon.Funguje i s tečkovou notací: {header.kontakt|dodavatel.email|'—'}.
Vlastnost "debug": true v sekci report zapne diagnostické značky v HTML výstupu:
{
"report": {
"debug": true
}
}
Pokud se placeholder {pole} nemůže resolvovat (pole v XML neexistuje), místo prázdné buňky se zobrazí červeně podbarvený text [MISSING: pole]. Pokud selže výpočet expr, zobrazí se [ERR: výraz].
Tip: Debug mód zapněte jen při vývoji šablony. V produkci by měl být vypnutý (nebo property vůbec neuvádějte).
Vlastnost "hideColumns" na sekci odebere zadané sloupce z výstupu. Je to opak printColumns — místo vyjmenování viditelných sloupců vyjmenujete ty, které chcete skrýt:
{
"sections": [{
"element": "data",
"hideColumns": "id, internal_code, poznamka",
"columns": {
"id": { "label": "ID" },
"nazev": { "label": "Název" },
"internal_code": { "label": "Interní kód" },
"cena": { "label": "Cena", "format": "N2" },
"poznamka": { "label": "Poznámka" }
}
}]
}
V tomto příkladu se zobrazí jen sloupce "Název" a "Cena". hideColumns se aplikuje před printColumns — můžete je kombinovat.
Vlastnost "alternateRowBackground" v sekci report nastaví barvu pozadí každého druhého řádku (sudé řádky):
{
"report": {
"alternateRowBackground": "#f9f9f9"
}
}
Hodnota je CSS barva (hex formát). Bez této vlastnosti mají všechny řádky bílé pozadí. Doporučené světlé odstíny: "#f9f9f9" (šedá), "#f0f8ff" (modrá), "#f5fff5" (zelená).
Operátor IN funguje v podmínkách where, visibleWhen a rowStyle.when. Testuje, zda hodnota pole patří do zadaného seznamu:
{
"sumRows": [
{
"sumLabel": "Aktivní celkem",
"where": "stav IN (A, B, C)",
"sumExpressions": [{ "field": "castka", "expr": "SUM(castka)", "format": "N2" }]
}
]
}
Porovnání je case-insensitive, hodnoty se automaticky trimují. Závorky jsou povinné, hodnoty oddělte čárkami.
Příklady:
"stav IN (A, P)" — stav je A nebo P"typ IN (faktura, dobropis)" — typ je faktura nebo dobropis"visibleWhen": "druh IN (1, 2, 3)" — zobrazit jen pro druhy 1, 2, 3Vlastnost "rowStyle" na sekci umožňuje obarvit nebo zvýraznit řádky podle podmínky. Definuje se jako pole pravidel — první pravidlo, jehož podmínka odpovídá, se aplikuje:
{
"sections": [{
"element": "data",
"rowStyle": [
{ "when": "stav=STORNO", "background": "#ffe0e0", "style": "italic" },
{ "when": "castka<0", "background": "#fff3cd", "color": "#856404" },
{ "when": "stav=A", "color": "#006600" }
],
"columns": { ... }
}]
}
Vlastnosti pravidla:
| Vlastnost | Popis | Příklad |
|---|---|---|
when |
Podmínka (stejná syntaxe jako where) |
"stav=STORNO", "castka<0", "typ IN (A, B)" |
background |
CSS barva pozadí celého řádku | "#ffe0e0" (růžová) |
color |
CSS barva textu celého řádku | "#006600" (zelená) |
style |
Styl písma: "bold" nebo "italic" |
"italic" |
Podmínky v when podporují všechny operátory: =, !=, >, <, >=, <=, IN(...), a také test na prázdnotu ("pole" = neprázdné, "!pole" = prázdné).
V template sloupcích a jiných šablonách můžete použít inline podmíněný text:
{
"columns": {
"stav_text": { "label": "Stav", "template": "{stav=A?Aktivní:stav=P?Pasivní:Zrušený}" }
}
}
Syntaxe: {podmínka?text_true:text_false}. Podmínky lze řetězit (else-if): {a=1?X:a=2?Y:Z}.
Ternární výrazy fungují i v sumLabel:
{
"sumLabel": "{osnova.ap=A?Zůstatek MD:Zůstatek DAL}"
}
A v sumExpressions.expr (s agregačními funkcemi):
{
"expr": "osnova.ap=A?SUM(md)-SUM(d):0"
}
Poznámka: V
exprse ternární výraz vyhodnotí jednou pro celou skupinu. Podmínka se resolvuje z group elementu nebo lookup kontextu. Pro per-subgroup logiku použijteSUMBY.
element v sekci odpovídá názvu XML elementu (názvy jsou case-sensitive)<row> elementy) pod daným elementemcolumns musí přesně odpovídat názvu atributu v XML (malá/velká písmena)visibleWhen, ověřte, že podmínka je splněnahide: true, odstraňte tuto vlastnost"N2" potřebuje číslo s tečkou jako oddělovačem (1234.56) v XML"align": "right" na sloupec s číslysumExpressions musí být na správném místě: na skupině (mezisoučty) nebo na sekci (celkový součet)"expr": "SUM(cena)" musí odpovídat klíči sloupce nebo XML atributu"field": "cena" říká, do kterého sloupce se výsledek zapíše{} nebo []"label": Název → "label": "Název""format": "N2" "align": "right" → "format": "N2", "align": "right"groupExpression musí odpovídat názvu atributu v XML řádcíchgroups = od vnější (méně časté změny) po vnitřní (častější změny)Místo absolutních mm hodnot můžete šířky sloupců zadat relativně k fontu. Výhoda: při změně dataFontPt se šířky automaticky přepočítají — nemusíte nic měnit.
| Zápis | Příklad | Význam |
|---|---|---|
"12c" |
12 znaků | šířka pro 12 znaků textu |
"15n2" |
N(15,2) | šířka pro 15 číslic s 2 des. místy (vč. oddělovačů) |
"8n" / "8n0" |
N(8,0) | šířka pro 8 číslic bez desetinných |
"d" |
datum | šířka pro datum (dd.MM.yyyy) |
"t" |
datetime | šířka pro datum a čas |
"16.1mm" |
stávající | beze změny (zpětná kompatibilita) |
Příklad:
{
"columns": {
"datum": { "label": "Datum", "width": "d", "format": "dd.MM.yyyy" },
"doklad": { "label": "Doklad", "width": "10c" },
"castka": { "label": "Částka", "width": "12n2", "format": "N2", "align": "right" },
"text": { "label": "Text", "width": "25c" }
}
}
Tip: Znakové jednotky fungují i v
minWidthamaxWidth. Stávající mm/px/% hodnoty fungují beze změny.
Tip:
CursorSchemaGeneratornyní generuje znakové jednotky automaticky ("d","12n2","20c"atd.).
Pro převod stávajících mm šířek na znakové jednotky:
*--- Konverze JSON stringu ---
lcNovy = loBuilder.ConvertJsonWidthsToCharUnits(lcJson)
*--- Konverze souboru (přepíše) ---
loBuilder.ConvertJsonFileWidthsToCharUnits("C:\sablony\prehled.json")
Konverze automaticky rozpozná typ sloupce (číslo, datum, text) z formátu a zarovnání.
Pokud potřebujete ručně nastavit "width" v mm na sloupcích (místo znakových jednotek nebo auto-výpočtu), použijte tuto referenční tabulku. Šířky odpovídají vzorci z CursorSchemaGenerator:
charWidthMm = fontPt × 0.6 × 25.4 / 72
gapMm = 2 × (0.5 − 0.015 × fontPt) × charWidthMm
paddingMm = 2.1 (CSS: 2×4px padding, fixed)
columnMm = effWidth × charWidthMm + gapMm + paddingMm
Padding (2.1 mm) je CSS td{padding:2px 4px} — s border-collapse:collapse je uvnitř šířky sloupce a nezávisí na velikosti fontu. Korekce pro numerické sloupce: mezera (oddělovač tisíců) = 0.35 znaku, čárka (des. oddělovač) = 0.45 znaku.
| Typ | Obraz (picture) | effWidth | 6 pt | 7 pt | 8 pt | 9 pt |
|---|---|---|---|---|---|---|
| Date | dd.MM.yyyy |
8.50 | 13.9 | 15.9 | 17.8 | 19.7 |
| DateTime | dd.MM.yyyy HH:mm |
14.00 | 20.9 | 24.0 | 27.1 | 30.2 |
| L | A/N |
3.00 | 7.0 | 7.7 | 8.5 | 9.2 |
| N0 (3 cifry) | 999 |
3.00 | 7.0 | 7.7 | 8.5 | 9.2 |
| N0 (6 cifer) | 999 999 |
6.65 | 11.6 | 13.1 | 14.6 | 16.2 |
| N0 (9 cifer) | 999 999 999 |
10.30 | 16.2 | 18.5 | 20.8 | 23.1 |
| N0 (12 cifer) | 999 999 999 999 |
13.95 | 20.9 | 23.9 | 27.0 | 30.1 |
| N2 (3+2) | 999,99 |
5.55 | 10.2 | 11.5 | 12.8 | 14.1 |
| N2 (6+2) | 999 999,99 |
9.20 | 14.8 | 16.9 | 19.0 | 21.0 |
| N2 (9+2) | 999 999 999,99 |
12.85 | 19.5 | 22.3 | 25.1 | 28.0 |
| N2 (12+2) | 999 999 999 999,99 |
16.50 | 24.1 | 27.7 | 31.3 | 34.9 |
| N3 (3+3) | 999,999 |
6.55 | 11.5 | 13.0 | 14.5 | 16.0 |
| N3 (6+3) | 999 999,999 |
10.20 | 16.1 | 18.4 | 20.7 | 22.9 |
| N3 (9+3) | 999 999 999,999 |
13.85 | 20.7 | 23.8 | 26.8 | 29.9 |
| N3 (12+3) | 999 999 999 999,999 |
17.50 | 25.4 | 29.2 | 33.0 | 36.8 |
| C(4) | xxxx (×1.2) |
4.80 | 9.2 | 10.4 | 11.5 | 12.6 |
| C(6) | xxxxxx |
6.00 | 10.8 | 12.2 | 13.5 | 14.9 |
| C(10) | xxxxxxxxxx |
10.00 | 15.8 | 18.1 | 20.3 | 22.5 |
| C(20) | 20 znaků | 20.00 | 28.5 | 32.9 | 37.3 | 41.6 |
| C(30) | 30 znaků | 30.00 | 41.2 | 47.7 | 54.2 | 60.6 |
| C(40) | 40 znaků | 40.00 | 53.9 | 62.5 | 71.1 | 79.7 |
| C(50) | 50 znaků | 50.00 | 66.6 | 77.4 | 88.1 | 98.7 |
Dostupná šířka stránky (po odečtení 2×8 mm okrajů):
| Formát | Portrait | Landscape |
|---|---|---|
| A4 | 194 mm | 281 mm |
| A3 | 281 mm | 404 mm |
Tip:
CursorSchemaGeneratorpočítá tyto šířky automaticky. Tabulku použijte když upravujete"width"ručně v JSON šabloně a chcete, aby sloupce správně seděly na stránku.
Poznámka: Krátké textové sloupce (≤ 4 znaky) se násobí koeficientem 1.2, aby záhlaví nebylo příliš stěsnané.
CursorSchemaGeneratorstandardně ořezává textové sloupce namaxLenString=20znaků.
Tip: Pokud používáte znakové jednotky (
"12c","15n2","d"atd.), přepočet není potřeba — šířky se přizpůsobí automaticky.
Pokud máte šířky v mm a měníte dataFontPt v JSON šabloně (např. z 8 na 7), je potřeba přepočítat šířky sloupců ("width").
Přesný vzorec (padding = fixní, content + gap = škálují se):
paddingMm = 2.1
width_nové = paddingMm + (width_staré - paddingMm) × (fontPt_nové / fontPt_staré)
Zjednodušený vzorec (chyba < 0.5 mm pro sloupce > 10 mm):
width_nové ≈ width_staré × (fontPt_nové / fontPt_staré)
Přepočítávací koeficienty (násobit stávající šířku):
| Z \ Na | 6 pt | 7 pt | 8 pt | 9 pt |
|---|---|---|---|---|
| 6 pt | — | 1.167 | 1.333 | 1.500 |
| 7 pt | 0.857 | — | 1.143 | 1.286 |
| 8 pt | 0.750 | 0.875 | — | 1.125 |
| 9 pt | 0.667 | 0.778 | 0.889 | — |
Příklad přesný (8pt → 7pt, sloupec 19.0mm):
2.1 + (19.0 - 2.1) × 7/8 = 2.1 + 14.79 = 16.9mm → "width": "16.9mm"
Příklad zjednodušený (stejný sloupec):
19.0 × 0.875 = 16.6mm → "width": "16.6mm" (rozdíl 0.3mm)
Tip: Koeficienty jsou prostý poměr fontů (
fontPt_nové / fontPt_staré). Nemusíte si je pamatovat — stačí vydělit: 7/8 = 0.875, 6/8 = 0.75 atd. Přesný vzorec se vyplatí u úzkých sloupců (< 12 mm), kde fixní padding 2.1 mm tvoří velký podíl.
Normálně sumRow počítá součet přes řádky aktuální skupiny. Property scope umožňuje počítat přes řádky nadřazené skupiny nebo celé sekce.
{
"sumLabel": "KZ k m.{obdobi}",
"scope": "ucet",
"where": "obdobi<={obdobi}",
"sumExpressions": [
{ "field": "md", "expr": "osnova.ap=A?SUM(md)-SUM(d):0", "format": "N2", "hideZero": true }
]
}
Typický případ: Skupina obdobi (měsíce) je vnořená v skupině ucet. KZ k měsíci potřebuje sčítat přes všechny řádky účtu, ne jen aktuální měsíc. "scope": "ucet" expanduje rozsah agregace na celou nadřazenou skupinu.
Where podmínka může obsahovat {field} — hodnota se dosadí z aktuální grupy:
"where": "obdobi<{obdobi}" — při období=3 → "obdobi<3""where": "obdobi<={obdobi}" — při období=3 → "obdobi<=3"Podmíněný výpočet: "expr": "podmínka?true_výraz:false_výraz"
{ "field": "md", "expr": "osnova.ap=A?SUM(md)-SUM(d):0", "format": "N2" }
Pokud účet je Aktivní (osnova.ap=A), spočítá MD−Dal. Jinak vrátí 0. Podmínka využívá lookup kontext (osnova.ap se dohledá z lookup tabulky).
Pro situace kde účty pod jednou syntetikou mají různé strany (A/P):
{ "field": "md", "expr": "SUMBY(ucet, osnova.ap=A?SUM(md)-SUM(d):0)", "hideZero": true }
SUMBY rozdělí řádky podle ucet, pro každý účet vyhodnotí ternární výraz (s jeho vlastním lookup kontextem) a sečte výsledky. Typicky pro SYN=343 (DPH) kde 3431 je Aktivní a 3432 je Pasivní.
Řádek se zobrazí jen při splnění podmínky:
{ "sumLabel": "PZ k m.{obdobi}", "visibleWhen": "obdobi>0" }
Řádek "Počáteční zůstatek k měsíci" se nezobrazí pro období 0 (samotný PZ).
Per-buňka blank if zero — buňka zůstane prázdná pokud výsledek je 0:
{ "field": "md", "expr": "osnova.ap=A?SUM(md)-SUM(d):0", "hideZero": true }
Rozdíl:
hideIfZerona sumRow skryje celý řádek.hideZerona sumExpression skryje jen jednu buňku.
forceNewPage a tableBreak mohou být řízeny z XML dat:
{
"groupExpression": "ucet",
"forceNewPage": "{parametr.lstrankovat}",
"tableBreak": "{parametr.lstrankovat}"
}
Hodnota "1" nebo "true" → zapnuto, ostatní → vypnuto.
Text přes celou stránku (vodoznak):
{ "report": { "watermark": "NÁVRH" } }
Podporuje {field} placeholdery: "watermark": "{header.stav}". Prázdný řetězec = nezobrazit.
Transformace textu ve formátu nebo šabloně:
{
"label": "Firma",
"format": "UPPER"
}
V šablonách: {firma:UPPER}, {nazev:PROPER}. Kombinace s formátem: {castka:N2:UPPER}.
| Modifikátor | Výsledek | Příklad |
|---|---|---|
:UPPER |
VELKÁ PÍSMENA | "efes" → "EFES" |
:LOWER |
malá písmena | "EFES" → "efes" |
:PROPER |
Velká Počáteční | "jan novák" → "Jan Novák" |
První neprázdná hodnota z více polí:
{ "template": "{nazev_cz|nazev_en|'Bez názvu'}" }
Znak | odděluje alternativy. Literál v uvozovkách 'text' slouží jako poslední fallback.
Pro ladění šablon — zobrazí chybové markery místo tichého ignorování:
{ "report": { "debug": true } }
V HTML: [MISSING: pole] (žlutý) a [ERR: výraz] (červený).
Opak printColumns — které sloupce NEUKÁZAT:
{ "sections": [{ "hideColumns": ["id", "internal_code"] }] }
Sloupce zůstávají dostupné pro výpočty a lookup, jen se nezobrazí.
Střídavé podbarvení sudých řádků:
{ "report": { "alternateRowBackground": "#f9f9f9" } }
Testování příslušnosti k množině ve where, visibleWhen, rowStyle:
{ "where": "typ IN (P, V, S)" }
Barva pozadí, tučné písmo nebo barva textu podle podmínky:
{
"rowStyles": [
{ "when": "stav=STORNO", "background": "#ffe0e0", "style": "bold", "color": "red" },
{ "when": "castka<0", "background": "#fff3e0" }
]
}
První matchující pravidlo se aplikuje na řádek.
Inline podmíněný text v libovolné šabloně:
{
"template": "{stav=A?Aktivní:Neaktivní}",
"label": "Účet {ucet} {osnova.ap=A?AKTIVNÍ:PASIVNÍ}"
}
Syntaxe: {podmínka?text_true:text_false}. Podmínky: =, !=, >, <, IN, field, !field.
| Co chci | Kam to napsat | Příklad |
|---|---|---|
| Změnit nadpis sloupce | columns.pole.label |
"label": "Nový název" |
| Skrýt sloupec | columns.pole.hide |
"hide": true |
| Formát čísla | columns.pole.format |
"format": "N2" |
| Formát data | columns.pole.format |
"format": "dd.MM.yyyy" |
| Zarovnat vpravo | columns.pole.align |
"align": "right" |
| Šířka sloupce | columns.pole.width |
"width": "80px" |
| Skrýt nuly | sections[].hideZero |
"hideZero": true |
| Záporná červeně | columns.pole.negativeRed |
"negativeRed": true |
| Na šířku | report.orientation |
"orientation": "landscape" |
| Součet sloupce | sumExpressions |
{ "field": "cena", "expr": "SUM(cena)", "format": "N2" } |
| Změnit název sestavy | report.title |
"title": "Nový název" |
| Bez čar mezi řádky | report.detailBorders |
"detailBorders": "vertical" |
| Větší písmo v Excelu | report.xlsxScale |
"xlsxScale": 1.3 |
| Podmíněný sloupec | columns.pole.visibleWhen |
"visibleWhen": "header.je_cizi_mena" |
| Průběžný součet | columns.pole.running |
"running": true, "resetAt": "ucet" |
V sekci columns přidejte nový klíč (= název XML atributu) s nastavením:
"columns": {
"kod": { "label": "Kód", "align": "center", "width": "60px" },
"nazev": { "label": "Název" },
"poznamka": { "label": "Poznámka" }
}
Na sekci nebo skupinu přidejte sumExpressions:
"sumExpressions": [
{ "field": "cena", "expr": "SUM(cena)", "format": "N2" }
],
"sumLabel": "Celkem"